package com.wwj.auction.schedule.scheduled;

import com.alibaba.fastjson.JSONObject;
import com.wwj.auction.common.entity.ot.Shop;
import com.wwj.auction.common.entity.ot.UserInfo;
import com.wwj.auction.common.entity.to.CreateOrderTo;
import com.wwj.auction.schedule.client.ServiceLoginClient;
import com.wwj.auction.schedule.client.ServiceOrderClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.LinkedHashMap;
import java.util.List;

/**
 * @author wwj
 * @EnableScheduling 开启定时任务
 * cron表达式：(cron=* * * * * *) 秒 分 时 日 月 周
 * @EnableAsync 开启异步任务
 */
@EnableScheduling
@EnableAsync
@Component
@Slf4j
@Controller
public class ScheduleTask {

    @Autowired
    private ServiceLoginClient serviceLoginClient;
    @Autowired
    private ServiceOrderClient serviceOrderClient;

    /**
     * 每一分钟扫描一次商品的拍卖时间
     * 若是有商品的结束拍卖时间已经过了，则找出该商品出价最高的买家
     * 生成该买家对应的订单，提供给其进行支付
     * <p>
     * <p>
     * 暂时做成接口形式，方便测试    http://localhost:14000/refresh/shop
     */
//    @Async
//    @Scheduled(cron = "* */1 * * * ?")
    @RequestMapping("/refresh/shop")
    public void scanShopTime() throws Exception {
        // 调用远程服务，获取到拍卖结束的商品列表
        List<LinkedHashMap<String, Object>> shopList = (List<LinkedHashMap<String, Object>>) serviceLoginClient.scanShop().getData().get("shopList");
        if (shopList != null && shopList.size() != 0) {
            // 否则，遍历集合中的商品，并找出最终成交的买家，并生成订单
            for (LinkedHashMap<String, Object> shopMap : shopList) {
                // 先将LinkedHashMap转为json
                String shopJson = JSONObject.toJSONString(shopMap);
                // 再将json转回实体
                Shop shop = JSONObject.parseObject(shopJson, Shop.class);
                System.out.println(shop);
                // 获取商品id
                Integer shopId = shop.getId();
                // 找到买家
                LinkedHashMap<String, Object> userInfoData = (LinkedHashMap<String, Object>) serviceLoginClient.findSeller(shopId).getData().get("userInfo");
                // 先将LinkedHashMap转为json
                String userInfoJson = JSONObject.toJSONString(userInfoData);
                // 再将json转回实体
                UserInfo userInfo = JSONObject.parseObject(userInfoJson, UserInfo.class);
                // 若用户为空，则没有买家对该商品进行出价，无需生成订单
                // 若用户不为空，则执行后续操作
                if (userInfo != null) {
                    // 生成订单
                    // OpenFeign不允许一个方法中出现两个@RequestBody注解，所以将用户信息和商品信息封装成一个json数据
                    CreateOrderTo createOrderTo = new CreateOrderTo();
                    createOrderTo.setUserInfo(userInfo);
                    createOrderTo.setShop(shop);
                    serviceOrderClient.create(createOrderTo);
                    // 生成订单后将商品状态修改为已成交
                    serviceLoginClient.status(2, shopId);
                }
            }
        } else {
            // 若集合为空，无需处理
        }
    }

    /**
     * 由于定时任务的线程池中只有一个线程，所以定时任务默认是阻塞的
     * 若不想让其阻塞，可以修改线程池中的线程数量
     * spring.task.scheduling.pool.size
     * <p>
     * 需要注意的是这种方式并不保证有效
     * <p>
     * 想解决阻塞问题，还可以将定时任务直接作为异步任务执行
     */
//    @Async
//    @Scheduled(cron = "* * * * * ?")
//    public void hello() {
//        log.info("hello......");
//    }
}
